﻿using System.Collections.Generic;
using System.Linq;

using VIT.DataAccessLayer;

namespace VIT.BusinessLogicLayer
{
    using VIT.DataTransferObjects.Presentation;
    using VIT.Library;
    using VIT.Library.Web;

    public class FileBLL : BLLBase
    {
        private readonly IFileLanguageDAL _fileLanguageDAL;
        private readonly ICategoryDAL _fileFolderDAL;
        private readonly ICategoryLanguageDAL _categoryLanguageDAL;

        private readonly string _domainStore;
        private readonly string _imageThumbPath;
        private readonly string _imageDetailPath;
        private readonly string _audioPath;
        private readonly string _videoPath;
        private readonly string _documentPath;

        private readonly URL _url;
        
        #region Constructor
        public FileBLL(string connectionString = "")
            : base(connectionString)
        {
            this._fileLanguageDAL = new FileLanguageDAL(this.DatabaseFactory);
            this._fileFolderDAL = new CategoryDAL(this.DatabaseFactory);
            this._categoryLanguageDAL = new CategoryLanguageDAL(DatabaseFactory);

            this._domainStore = SettingsManager.AppSettings.DomainStore;
            this._imageThumbPath = SettingsManager.Constants.LinkPictureThumbFile;
            this._imageDetailPath = SettingsManager.Constants.LinkPictureDetailFile;
            this._audioPath = SettingsManager.Constants.LinkAudioFile;
            this._videoPath = SettingsManager.Constants.LinkVideoFile;
            this._documentPath = SettingsManager.Constants.LinkDocumentFile;

            this._url = new URL();
        }
        #endregion

        #region File
        public FileDto GetFileById(int id, string laguage)
        {
            var query = this._fileLanguageDAL.GetAllIncludeItemView()
                .Where(file => file.File.Item.IsPublished && file.File.Item.HasDeleted == false)
                .Where(file => file.FileId == id && file.LanguageId == laguage)
                .Select(file => new FileDto
                {
                    FileName = file.File.FileName,
                    Title = file.Title,
                    FolderId = file.File.CategoryId ?? 0,
                    Id = file.FileId,
                    Likes = file.File.Item.ItemLike == null ? 0 : file.File.Item.ItemLike.Likes,
                    DisLikes = file.File.Item.ItemLike == null ? 0 : file.File.Item.ItemLike.UnLikes,
                    Views = file.File.Item.ItemView == null ? 0 : file.File.Item.ItemView.Views,
                    Size = file.File.Size ?? 0,
                    DisplayDate = file.File.Item.CreateDate,
                    Order = file.File.Item.Orders,
                    Tag = file.File.Tag
                });

            var data = query.FirstOrDefault();
            return data;
        }

        public IList<FileDto> GetFileByTagAndFolder(string laguage, int folderId, string tag, out int totalPage, int skip = 0, int take = 0)
        {
            var query = this._fileLanguageDAL.GetAllIncludeItemView()
               .Where(file => file.File.Item.IsPublished && file.File.Item.HasDeleted == false && file.LanguageId == laguage);

            if (!string.IsNullOrEmpty(tag))
            {
                var arrTag = tag.Split('_');
                query = arrTag.Aggregate(query, (current, t) => current.Where(c => c.File.Tag.Contains(t)));
            }

            if(folderId>0)
                query = query.Where(file => file.File.CategoryId == folderId);

            var querydto = query.Select(file => new FileDto
               {
                   FileName = file.File.FileName,
                   Title = file.Title,
                   FolderId = file.File.CategoryId ?? 0,
                   Id = file.FileId,
                   Likes = file.File.Item.ItemLike == null ? 0 : file.File.Item.ItemLike.Likes,
                   DisLikes = file.File.Item.ItemLike == null ? 0 : file.File.Item.ItemLike.UnLikes,
                   Views = file.File.Item.ItemView == null ? 0 : file.File.Item.ItemView.Views,
                   Size = file.File.Size ?? 0,
                   DisplayDate = file.File.Item.CreateDate,
                   Tag = file.File.Tag,
                   Order = file.File.Item.Orders
               });

            totalPage = querydto.Count();
            querydto = querydto.OrderBy(o => o.Order).ThenByDescending(o => o.DisplayDate);
            if (skip > 0) querydto = querydto.Skip(skip);
            if (take > 0) querydto = querydto.Take(take);

            var data = querydto.ToList();

            return data;
        }

        public IList<FileDto> GetFileNewFolder(string type, string language, out int totalPage, int skip = 0, int take = 0)
        {
            totalPage = 0;
            var folderQuery = _fileFolderDAL.GetAll()
                .Where(category => category.TypeId == type)
                .OrderBy(category => category.Item.Orders)
                .ThenByDescending(category => category.Item.CreateByUser);

            var folder = folderQuery.FirstOrDefault();
            if (folder != null)
            {
                var data = GetFileByTagAndFolder(language, folder.Id, string.Empty, out totalPage, skip, take);
                return data;
            }
            return new List<FileDto>();
        }

        public IList<FileDto> GetFileOfMember(string language, string userName)
        {
            var query = this._fileLanguageDAL.GetAllIncludeItemView()
               .Where(file => file.File.Item.HasDeleted == false && file.LanguageId == language)
               .Where(file => file.File.Item.CreateByUser == userName);

            var querydto = query.Select(file => new FileDto
            {
                FileName = file.File.FileName,
                Title = file.Title,
                FolderId = file.File.CategoryId ?? 0,
                Id = file.FileId,
                Likes = file.File.Item.ItemLike == null ? 0 : file.File.Item.ItemLike.Likes,
                DisLikes = file.File.Item.ItemLike == null ? 0 : file.File.Item.ItemLike.UnLikes,
                Views = file.File.Item.ItemView == null ? 0 : file.File.Item.ItemView.Views,
                Size = file.File.Size ?? 0,
                DisplayDate = file.File.Item.CreateDate,
                Order = file.File.Item.Orders,
                Tag = file.File.Tag,
                Published = file.File.Item.IsPublished
            });

            var data = querydto.ToList();

            return data.ToList();
        }
        #endregion

        #region Document
        public FileDocumentDto GetDocumentById(int id, string language, int companyId)
        {
            var query = _fileLanguageDAL.GetAllDocumentIncludeViewCategory()
                .Where(doc => doc.LanguageId == language && doc.File.FileDocument.FileId == id)
                .Where(doc => doc.File.Item.CompanyId == companyId)
                .Select(doc => new FileDocumentDto
                {
                    Id = doc.FileId,
                    Title = doc.Title,
                    Description = doc.Description,

                    FileName = doc.File.FileName,
                    FolderId = doc.File.CategoryId,
                    Size = doc.File.Size,
                    Tag = doc.File.Tag,

                    Likes = doc.File.Item.ItemLike == null ? 0 : doc.File.Item.ItemLike.Likes,
                    DisLikes = doc.File.Item.ItemLike == null ? 0 : doc.File.Item.ItemLike.UnLikes,
                    Views = doc.File.Item.ItemView == null ? 0 : doc.File.Item.ItemView.Views,

                    FolderName = doc.File.Category.CategoryLanguages.FirstOrDefault(d => d.LanguageId == language).Title,
                    
                    Author = doc.File.FileDocument.Author,
                    Extension = doc.File.FileDocument.Extension,
                    Pages = doc.File.FileDocument.Pages,
                    Image = doc.File.FileDocument.Image,
                    LanguageId = doc.File.FileDocument.LanguageId,

                    CreateByUser = doc.File.Item.CreateByUser
                });

            var data = query.FirstOrDefault();

            if (data != null)
            {
                var documentPath = string.Format(this._documentPath, companyId);
                data.FilePath = this._url.VirtualPath(documentPath + data.FileName);
            }

            return data;
        }

        public IList<FileDocumentDto> GetListDocument(string language, int companyId, out int totalPage, int skip = 0, int take = 0)
        {
            var query = _fileLanguageDAL.GetAllDocumentIncludeViewCategory()
               .Where(doc => doc.LanguageId == language)
               .Where(doc => doc.File.FileDocument != null)
               .Where(doc => doc.File.Item.CompanyId == companyId)
               .OrderBy(doc => doc.File.Item.Orders)
               .ThenByDescending(doc => doc.File.Item.CreateDate)
               .Select(doc => new FileDocumentDto
               {
                   Id = doc.FileId,
                   Title = doc.Title,
                   Description = doc.Description,

                   FileName = doc.File.FileName,
                   FolderId = doc.File.CategoryId,
                   Size = doc.File.Size,
                   Tag = doc.File.Tag,

                   Likes = doc.File.Item.ItemLike == null ? 0 : doc.File.Item.ItemLike.Likes,
                   DisLikes = doc.File.Item.ItemLike == null ? 0 : doc.File.Item.ItemLike.UnLikes,
                   Views = doc.File.Item.ItemView == null ? 0 : doc.File.Item.ItemView.Views,

                   FolderName = doc.File.Category.CategoryLanguages.FirstOrDefault(d => d.LanguageId == language).Title,

                   Author = doc.File.FileDocument.Author,
                   Extension = doc.File.FileDocument.Extension,
                   Pages = doc.File.FileDocument.Pages,
                   Image = doc.File.FileDocument.Image,
                   LanguageId = doc.File.FileDocument.LanguageId,

                   CreateByUser = doc.File.Item.CreateByUser
               });

            totalPage = query.Count();
            if (skip > 0) query = query.Skip(skip);
            if (take > 0) query = query.Take(take);

            var data = query.ToList();

            var documentPath = string.Format(this._documentPath, companyId);
            data.ForEach(dto => dto.FilePath = this._url.VirtualPath(documentPath + dto.FileName));
            data.ForEach(dto => dto.FilePath = this._url.VirtualPath(documentPath + dto.FileName));

            return data;
        }

        public List<RSSCommentDto> GetCommentForRSS(string language, out int totalPage, int skip = 0, int take = 0)
        {
            var query = _fileLanguageDAL.GetAllIncludeItem()
                .Where(fileLanguage => fileLanguage.LanguageId == language)
                .Select(file => new RSSCommentDto
                {
                    User = file.File.Item.CreateByUser,
                    Descripton = file.Description,
                    Time = file.File.Item.CreateDate,
                    Id = file.FileId,
                    Title = file.Title
                });

            totalPage = query.Count();
            if (skip > 0) query = query.Skip(skip);
            if (take > 0) query = query.Take(take);

            var data = query.ToList();

            return data;
        }

        public List<DataSimpleDto> GetDataSimpleDocument(int companyId, string languageId, int categoryId, bool inChildCat, out int totalPage, int Skip = 0, int Take = 0)
        {
            var query = this._fileLanguageDAL.GetAll()
                .Where(e => e.File.Item.CompanyId == companyId && e.LanguageId == languageId && e.File.Item.IsPublished && !e.File.Item.HasDeleted)
                .Where(e => e.File.FileDocument != null);

            if (categoryId > 0)
            {
                IList<int> listCategory;
                if (inChildCat)
                {
                    var categorys = this._categoryLanguageDAL.GetAllIncludeItem()
                        .Where(cat => cat.Category.Item.IsPublished && cat.LanguageId == languageId)
                        .Select(cat => new CategorySimpleDto
                        {
                            ID = cat.CategoryId,
                            Title = cat.Title,
                            ParentId = cat.Category.ParentId
                        }).ToList();

                    listCategory = this.GetAllChildId(categorys, categoryId);
                }
                else
                {
                    listCategory = new List<int>();
                    listCategory.Add(categoryId);
                }

                query = query.Where(c => listCategory.Contains(c.File.CategoryId ?? 0));
            }

            var selected = query.OrderBy(e => e.File.Item.Orders)
                .ThenByDescending(e => e.File.Item.CreateDate)
                .Select(a => new DataSimpleDto
                {
                    Id = a.FileId,
                    CategoryId = a.File.CategoryId ?? 0,
                    Title = a.Title,
                    Description = a.Description,
                    ImagePath = a.File.FileDocument.Image,
                    URL = a.File.FileName,
                });

            totalPage = selected.Count();
            if (Skip > 0) selected = selected.Skip(Skip);
            if (Take > 0) selected = selected.Take(Take);

            var data = selected.ToList();

            var imagePathThumb = string.Format(this._documentPath, companyId);
            foreach (var item in data)
            {
                item.ImagePath = this._url.VirtualPath(imagePathThumb + item.ImagePath);
                item.URL = this._url.VirtualPath(imagePathThumb + item.URL);
            }

            return data;
        }

        public List<DataSimpleDto> SearchDataSimpleDocument(int companyId, string languageId, string key, out int totalPage, int Skip = 0, int Take = 0)
        {
            var query = this._fileLanguageDAL.GetAll()
                .Where(e => e.File.Item.CompanyId == companyId && e.LanguageId == languageId && e.File.Item.IsPublished && !e.File.Item.HasDeleted)
                .Where(e => e.File.FileDocument != null)
                .Where(e => e.Title.Contains(key) || e.Description.Contains(key) || e.File.FileDocument.Author.Contains(key));            

            var selected = query.OrderBy(e => e.File.Item.Orders)
                .ThenByDescending(e => e.File.Item.CreateDate)
                .Select(a => new DataSimpleDto
                {
                    Id = a.FileId,
                    CategoryId = a.File.CategoryId ?? 0,
                    Title = a.Title,
                    Description = a.Description,
                    ImagePath = a.File.FileDocument.Image,
                    URL = a.File.FileName,
                });

            totalPage = selected.Count();
            if (Skip > 0) selected = selected.Skip(Skip);
            if (Take > 0) selected = selected.Take(Take);

            var data = selected.ToList();

            var imagePathThumb = string.Format(this._documentPath, companyId);
            foreach (var item in data)
            {
                item.ImagePath = this._url.VirtualPath(imagePathThumb + item.ImagePath);
                item.URL = this._url.VirtualPath(imagePathThumb + item.URL);
            }

            return data;
        }
        #endregion

        #region Video
        public List<FileVideoDto> GetVideoByCategory(int categoryId, string laguage, int companyId, out int totalPage, int skip = 0, int take = 0)
        {
            totalPage = 0;
            var queryfolder = _fileFolderDAL.GetAll()
                .Where(c => c.Item.CompanyId == companyId && c.Item.IsPublished)
                .Where(category => category.Id == categoryId);

            var folder = queryfolder.FirstOrDefault();

            if (folder != null)
            {
                var file = _fileLanguageDAL.GetAll()
                    .Where(o => o.File.CategoryId == folder.Id && o.File.Item.IsPublished && o.LanguageId == laguage)
                    .Where(o => o.File.FileVideo != null)
                    .OrderBy(o => o.File.Item.Orders)
                    .ThenByDescending(o => o.File.Item.CreateDate)
                    .Select(l => new FileVideoDto
                    {
                        Id = l.File.Id,
                        Embed = l.File.FileVideo.Embed,
                        FileName = l.File.FileName,
                        Title = l.Title,
                        Description = l.Description
                    });
                totalPage = file.Count();
                if (skip > 0) file = file.Skip(skip);
                if (take > 0) file = file.Take(take);

                var data = file.ToList();

                var videoPath = string.Format(this._videoPath, companyId);
                data.ForEach(dto => dto.FilePath = this._url.VirtualPath(videoPath + dto.FileName));

                return data;
            }
            return null;
        }

        public List<DataSimpleDto> GetDataSimpleVideo(int companyId, string languageId, int categoryId, bool inChildCat, out int totalPage, int Skip = 0, int Take = 0)
        {
            var query = this._fileLanguageDAL.GetAll()
                .Where(e => e.File.Item.CompanyId == companyId && e.LanguageId == languageId && e.File.Item.IsPublished && !e.File.Item.HasDeleted)
                .Where(e => e.File.FileVideo != null);

            if (categoryId > 0)
            {
                IList<int> listCategory;
                if (inChildCat)
                {
                    var categorys = this._categoryLanguageDAL.GetAllIncludeItem()
                        .Where(cat => cat.Category.Item.IsPublished && cat.LanguageId == languageId)
                        .Select(cat => new CategorySimpleDto
                        {
                            ID = cat.CategoryId,
                            Title = cat.Title,
                            ParentId = cat.Category.ParentId
                        }).ToList();

                    listCategory = this.GetAllChildId(categorys, categoryId);
                }
                else
                {
                    listCategory = new List<int>();
                    listCategory.Add(categoryId);
                }

                query = query.Where(c => listCategory.Contains(c.File.CategoryId ?? 0));
            }

            var selected = query.OrderBy(e => e.File.Item.Orders)
                .ThenByDescending(e => e.File.Item.CreateDate)
                .Select(a => new DataSimpleDto
                {
                    Id = a.FileId,
                    CategoryId = a.File.CategoryId ?? 0,
                    Title = a.Title,
                    Description = a.Description,
                    URL = a.File.FileName
                });

            totalPage = selected.Count();
            if (Skip > 0) selected = selected.Skip(Skip);
            if (Take > 0) selected = selected.Take(Take);

            var data = selected.ToList();

            var imagePathThumb = string.Format(this._videoPath, companyId);
            foreach (var item in data)
            {
                item.URL = this._url.VirtualPath(imagePathThumb + item.URL);
            }

            return data;
        }

        public List<DataSimpleDto> SearchDataSimpleVideo(int companyId, string languageId, string key, out int totalPage, int Skip = 0, int Take = 0)
        {
            var query = this._fileLanguageDAL.GetAll()
                .Where(e => e.File.Item.CompanyId == companyId && e.LanguageId == languageId && e.File.Item.IsPublished && !e.File.Item.HasDeleted)
                .Where(e => e.File.FileVideo != null)
                .Where(e => e.Title.Contains(key) || e.Description.Contains(key) || e.File.FileVideo.Writer.Contains(key) || e.File.FileVideo.Director.Contains(key) || e.File.FileVideo.Editor.Contains(key));     

            var selected = query.OrderBy(e => e.File.Item.Orders)
                .ThenByDescending(e => e.File.Item.CreateDate)
                .Select(a => new DataSimpleDto
                {
                    Id = a.FileId,
                    CategoryId = a.File.CategoryId ?? 0,
                    Title = a.Title,
                    Description = a.Description,
                    URL = a.File.FileName
                });

            totalPage = selected.Count();
            if (Skip > 0) selected = selected.Skip(Skip);
            if (Take > 0) selected = selected.Take(Take);

            var data = selected.ToList();

            var imagePathThumb = string.Format(this._videoPath, companyId);
            foreach (var item in data)
            {
                item.URL = this._url.VirtualPath(imagePathThumb + item.URL);
            }

            return data;
        }
        #endregion

        #region Audio
        public List<FileAudioDto> GetAudioByCategory(int categoryId, string laguage, int companyId, out int totalPage, int skip = 0, int take = 0)
        {
            totalPage = 0;
            var queryfolder = _fileFolderDAL.GetAll()
                .Where(c => c.Item.CompanyId == companyId && c.Item.IsPublished)
                .Where(category => category.Id == categoryId);

            var folder = queryfolder.FirstOrDefault();

            if (folder != null)
            {
                var file = _fileLanguageDAL.GetAll()
                    .Where(o => o.File.CategoryId == folder.Id && o.File.Item.IsPublished && o.LanguageId == laguage)
                    .Where(o => o.File.FileAudio != null)
                    .Select(l => new FileAudioDto
                    {
                        FileName = l.File.FileName,
                        Title = l.Title,
                        Description = l.Description,
                        Id = l.File.Id,
                        Embed = l.File.FileVideo.Embed
                    });
                totalPage = file.Count();
                if (skip > 0) file = file.Skip(skip);
                if (take > 0) file = file.Take(take);

                var data = file.ToList();

                var audioPath = string.Format(this._audioPath, companyId);
                data.ForEach(dto => dto.FilePath = this._url.VirtualPath(audioPath + dto.FileName));

                return data;
            }
            return null;
        }

        public List<DataSimpleDto> GetDataSimpleAudio(int companyId, string languageId, int categoryId, bool inChildCat, out int totalPage, int Skip = 0, int Take = 0)
        {
            var query = this._fileLanguageDAL.GetAll()
                .Where(e => e.File.Item.CompanyId == companyId && e.LanguageId == languageId && e.File.Item.IsPublished && !e.File.Item.HasDeleted)
                .Where(e => e.File.FileAudio != null);

            if (categoryId > 0)
            {
                IList<int> listCategory;
                if (inChildCat)
                {
                    var categorys = this._categoryLanguageDAL.GetAllIncludeItem()
                        .Where(cat => cat.Category.Item.IsPublished && cat.LanguageId == languageId)
                        .Select(cat => new CategorySimpleDto
                        {
                            ID = cat.CategoryId,
                            Title = cat.Title,
                            ParentId = cat.Category.ParentId
                        }).ToList();

                    listCategory = this.GetAllChildId(categorys, categoryId);
                }
                else
                {
                    listCategory = new List<int>();
                    listCategory.Add(categoryId);
                }

                query = query.Where(c => listCategory.Contains(c.File.CategoryId ?? 0));
            }

            var selected = query.OrderBy(e => e.File.Item.Orders)
                .ThenByDescending(e => e.File.Item.CreateDate)
                .Select(a => new DataSimpleDto
                {
                    Id = a.FileId,
                    CategoryId = a.File.CategoryId ?? 0,
                    Title = a.Title,
                    Description = a.Description,
                    URL = a.File.FileName
                });

            totalPage = selected.Count();
            if (Skip > 0) selected = selected.Skip(Skip);
            if (Take > 0) selected = selected.Take(Take);

            var data = selected.ToList();

            var imagePathThumb = string.Format(this._audioPath, companyId);
            foreach (var item in data)
            {
                item.URL = this._url.VirtualPath(imagePathThumb + item.URL);
            }

            return data;
        }

        public List<DataSimpleDto> SearchDataSimpleAudio(int companyId, string languageId, string key, out int totalPage, int Skip = 0, int Take = 0)
        {
            var query = this._fileLanguageDAL.GetAll()
                .Where(e => e.File.Item.CompanyId == companyId && e.LanguageId == languageId && e.File.Item.IsPublished && !e.File.Item.HasDeleted)
                .Where(e => e.File.FileAudio != null)
                 .Where(e => e.Title.Contains(key) || e.Description.Contains(key) || e.File.FileAudio.Author.Contains(key));     

            var selected = query.OrderBy(e => e.File.Item.Orders)
                .ThenByDescending(e => e.File.Item.CreateDate)
                .Select(a => new DataSimpleDto
                {
                    Id = a.FileId,
                    CategoryId = a.File.CategoryId ?? 0,
                    Title = a.Title,
                    Description = a.Description,
                    URL = a.File.FileName
                });

            totalPage = selected.Count();
            if (Skip > 0) selected = selected.Skip(Skip);
            if (Take > 0) selected = selected.Take(Take);

            var data = selected.ToList();

            var imagePathThumb = string.Format(this._audioPath, companyId);
            foreach (var item in data)
            {
                item.URL = this._url.VirtualPath(imagePathThumb + item.URL);
            }

            return data;
        }
        #endregion

        #region Picture
        public List<FileImageDto> GetImageByCategory(int categoryId, string laguage, int companyId, out int totalPage, int skip = 0, int take = 0)
        {
            totalPage = 0;
            var queryfolder = _fileFolderDAL.GetAll()
                .Where(c => c.Item.CompanyId == companyId && c.Item.IsPublished)
                .Where(category => category.Id == categoryId);

            var folder = queryfolder.FirstOrDefault();

            if (folder != null)
            {
                var file = _fileLanguageDAL.GetAll()
                    .Where(o => o.File.CategoryId == folder.Id && o.File.Item.IsPublished && o.LanguageId == laguage)
                    .Select(l => new FileImageDto
                    {
                        Id = l.File.Id,
                        Title = l.Title,
                        Description = l.Description,
                        FileName = l.File.FileName,
                    });

                totalPage = file.Count();
                if (skip > 0) file = file.Skip(skip);
                if (take > 0) file = file.Take(take);

                var data = file.ToList();

                // update path image
                var imageDetailPath = string.Format(this._imageDetailPath, companyId);
                var imageThumbPath = string.Format(this._imageThumbPath, companyId);
                foreach (var dto in data)
                {
                    dto.FileDetailPath = this._url.VirtualPath(imageDetailPath + dto.FileName);
                    dto.FileThumbPath = this._url.VirtualPath(imageThumbPath + dto.FileName);
                }

                return data;
            }
            return null;
        }

        public List<DataSimpleDto> GetDataSimplePicture(int companyId, string languageId, int categoryId, bool inChildCat, out int totalPage, int Skip = 0, int Take = 0)
        {
            var query = this._fileLanguageDAL.GetAll()
                .Where(e => e.File.Item.CompanyId == companyId && e.LanguageId == languageId && e.File.Item.IsPublished && !e.File.Item.HasDeleted)
                .Where(e => e.File.FileVideo == null && e.File.FileAudio == null && e.File.FileDocument == null);

            if (categoryId > 0)
            {
                IList<int> listCategory;
                if (inChildCat)
                {
                    var categorys = this._categoryLanguageDAL.GetAllIncludeItem()
                        .Where(cat => cat.Category.Item.IsPublished && cat.LanguageId == languageId)
                        .Select(cat => new CategorySimpleDto
                        {
                            ID = cat.CategoryId,
                            Title = cat.Title,
                            ParentId = cat.Category.ParentId
                        }).ToList();

                    listCategory = this.GetAllChildId(categorys, categoryId);
                }
                else
                {
                    listCategory = new List<int>();
                    listCategory.Add(categoryId);
                }

                query = query.Where(c => listCategory.Contains(c.File.CategoryId ?? 0));
            }

            var selected = query.OrderBy(e => e.File.Item.Orders)
                .ThenByDescending(e => e.File.Item.CreateDate)
                .Select(a => new DataSimpleDto
                {
                    Id = a.FileId,
                    CategoryId = a.File.CategoryId ?? 0,
                    Title = a.Title,
                    Description = a.Description,
                    ImagePath = a.File.FileName
                });

            totalPage = selected.Count();
            if (Skip > 0) selected = selected.Skip(Skip);
            if (Take > 0) selected = selected.Take(Take);

            var data = selected.ToList();

            var imagePathThumb = string.Format(this._imageThumbPath, companyId);
            foreach (var item in data)
            {
                item.ImagePath = this._url.VirtualPath(imagePathThumb + item.ImagePath);
            }

            return data;
        }
        #endregion

        #region Private method
        private IList<int> GetAllChildId(IList<CategorySimpleDto> category, int? parentId)
        {
            var subcats = category.Where(o => o.ParentId == parentId).ToList(); // lay tat ca con cua parentID

            var result = new List<int>();
            foreach (var subcat in subcats)
            {
                if (subcat != null)
                {
                    var temp = this.GetAllChildId(category, subcat.ID);

                    result.Add(subcat.ID);
                    if (temp != null && temp.Count > 0)
                    {
                        result.AddRange(temp);
                    }
                }
            }

            return result;
        }
        #endregion
    }
}
